camera前置摄像头左右镜像问题

您所在的位置:网站首页 Android camera2 翻转 camera前置摄像头左右镜像问题

camera前置摄像头左右镜像问题

2023-08-17 11:36| 来源: 网络整理| 查看: 265

需求:使用虹软活体检测时,需要截取检测框中的人脸

Camera.PreviewCallback中onPreviewFrame(byte[] data, Camera camera)返回的data字节数组不是bitmap 的编码,需要转移一下: 下面列出几种方法: 1.有可能发生内存溢出:

YuvImage image = new YuvImage(bytes, ImageFormat.NV21, width, height, null); ByteArrayOutputStream os = new ByteArrayOutputStream(bytes.length); if (!image.compressToJpeg(rect, 100, os)) { return null; } byte[] tmp = os.toByteArray(); Bitmap bmp = BitmapFactory.decodeByteArray(tmp, 0, tmp.length);

2.转码:

//YCbCr_420_SP-->(解码,yuv420sp转为RGB格式 ) static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { final int frameSize = width * height; for (int j = 0, yp = 0; j < height; j++) { int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; for (int i = 0; i < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((r > 2) & 0xff00) | ((b >> 10) & 0xff); } } }

或者

//图片字节转换 public static Bitmap rawByteArray2RGBABitmap2(byte[] data, int width, int height) { int frameSize = width * height; int[] rgba = new int[frameSize]; for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) { int y = (0xff & ((int) data[i * width + j])); int u = (0xff & ((int) data[frameSize + (i >> 1) * width + (j & ~1)])); int v = (0xff & ((int) data[frameSize + (i >> 1) * width + (j & ~1) + 1])); y = y < 16 ? 16 : y; int r = Math.round(1.164f * (y - 16) + 1.596f * (v - 128)); int g = Math.round(1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128)); int b = Math.round(1.164f * (y - 16) + 2.018f * (u - 128)); r = r < 0 ? 0 : (r > 255 ? 255 : r); g = g < 0 ? 0 : (g > 255 ? 255 : g); b = b < 0 ? 0 : (b > 255 ? 255 : b); rgba[i * width + j] = 0xff000000 + (b = Build.VERSION_CODES.JELLY_BEAN_MR1) { ScriptIntrinsicYuvToRGB= yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); }

现在说正题了: 前置左右镜像问题:

final YuvImage image = new YuvImage(bytes, ImageFormat.NV21, width, height, null); ByteArrayOutputStream os = new ByteArrayOutputStream(bytes.length); if (!image.compressToJpeg(rect, 100, os)) { return null; } byte[] tmp = os.toByteArray(); Bitmap bmp = BitmapFactory.decodeByteArray(tmp, 0, tmp.length); Matrix matrix = new Matrix(); Log.i(TAG, "getBitmapFromByte: displayOrientation-->" + displayOrientation); matrix.preRotate(360 - displayOrientation); //重点--->前置摄像头生成图片 左右镜像问题 matrix.postScale(-1, 1); return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp .getHeight(), matrix, true);

镜像上下颠倒,需要设置相机预览的显示方向

public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { try { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } catch (Exception e) { CommonUtil.printStackTrace(e); } }

之后做旋转:

Matrix matrix = new Matrix(); matrix.postRotate(CamParaUtil.getCameraDisplayOrientation(StickerMakeActivity.this, mCameraId, mCamera)); matrix.postScale(scale, isCameraFront() ? -scale : scale); Bitmap cropRotateScaled = Bitmap.createBitmap(origin, (int) resultRect.left, (int) resultRect.top, (int) resultRect.width(), (int) resultRect.height(), matrix, true);

其中用到的方法:

public static int getCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { int result = 90; try { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } } catch (Exception e) { CommonUtil.printStackTrace(e); } return result; }

镜像来自自android开发步步为营之112:关于Camera镜像上下左右颠倒问题的解决办法



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3